/**
 *******************************************************************************
 * @FileName  : tlsr825x_pwm.c
 * @Author    : GaoQiu
 * @CreateDate: 2020-09-10
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */
#include "tlsr825x_pwm.h"

/**
 * @brief  : PWM initliazation.
 * @param  : PWM_ClkDiv       clock div. PWM_CLK = SYSCLK/(DIV+1)
 * @return : None.
 */
void PWM_Init(uint8_t PWM_ClkDiv)
{
	PWM->CLK_DIV = PWM_ClkDiv;
}

/**
 * @brief  : Set PWM pulse parameter.
 * @param  : PWMx        can be PWM0/PWM1/PWM2...
 * @param  : duty        PWM duty,  unit: the number of PWM clock tick.
 * @param  : cycle       PWM cycle, unit: the number of PWM clock tick.
 * @return : None.
 */
void PWM_SetPulse(uint8_t PWMx, uint16_t duty, uint16_t cycle)
{
	uint16_t *pPwmCmp = (uint16_t *)&PWM->CMP0   + PWMx * 2;
	uint16_t *pPwmCyc = (uint16_t *)&PWM->CYCLE0 + PWMx * 2;

	*pPwmCmp = duty;
	*pPwmCyc = cycle;
}

/**
 * @brief  : Set PWM pulse2 parameter.
 *           !!!Note: PWM can support two pulses with different frequency parameters
 *                    at the same time. The transmission is controlled by the corresponding enable bit.
 *
 * @param  : PWMx        only use for PWM0.
 * @param  : duty        PWM duty,  unit: the number of PWM clock tick.
 * @param  : cycle       PWM cycle, unit: the number of PWM clock tick.
 * @return : None.
 */
void PWM_SetPulse2(uint8_t PWMx, uint16_t duty, uint16_t cycle)
{
	uint16_t *pPwmCmp = (uint16_t *)&PWM->CMP0_SHADOW;
	uint16_t *pPwmCyc = (uint16_t *)&PWM->CYCLE0_SHADOW;

	*pPwmCmp = duty;
	*pPwmCyc = cycle;
}

/**
 * @brief  : Set PWM mode.
 * @param  : PWMx        only use for PWM0.
 * @param  : PWM_Mode    can be PWM_MODE_NORMAL/PWM_MODE_CNT...
 * @return : None.
 */
void PWM_SetMode(uint8_t PWMx, uint8_t PWM_Mode)
{
	PWM->MODE = PWM_Mode;
}

/**
 * @brief  : Set PWM pulse number.
 * @param  : PWMx        only use for PWM0.
 * @param  : num         the number of PWM pulse.
 * @return : None.
 */
void PWM_SetPulseNum(uint8_t PWMx, uint16_t num)
{
	PWM->PNUM0 = num;
}

/**
 * @brief  : Set PWM enable.
 * @param  : PWMx        can be PWM0/PWM1/PWM2....
 * @return : None.
 */
void PWM_Enable(uint8_t PWMx)
{
	if(PWMx == PWM0){
		PWM->EN |= PWM0_EN;
	}
	else{
		PWM->EN |= (1<<PWMx);
	}
}

/**
 * @brief  : Set PWM enable/disable.
 * @param  : PWMx        can be PWM0/PWM1/PWM2....
 * @return : None.
 */
void PWM_Disable(uint8_t PWMx)
{
	if(PWMx == PWM0){
		PWM->EN &= ~PWM0_EN;
	}
	else{
		PWM->EN &= ~(1<<PWMx);
	}
}

/**
 * @brief  : Set PWM interrupt.
 * @param  : PWMx        can be PWM0/PWM1...
 * @param  : PWM_IT      can be PWM_IT_Cnt/PWM_IT_Dma/PWM_IT_Frame0...
 * @param  : enable      enable / disable PWM interrupt.
 * @return : None.
 */
void PWM_ITConfig(uint8_t PWMx, uint8_t PWM_IT, bool_t enable)
{
	//TODO:
}

/**
 * @brief  : Get PWM interrupt flag.
 * @param  : PWMx          can be PWM0/PWM1...
 * @param  : PWM_IT_Flag   can be PWM_IT_Flag_Cnt/PWM_IT_Flag_Dma/PWM_IT_Flag_Frame0...
 * @return : None.
 */
uint8_t PWM_GetITFlag(uint8_t PWMx, uint8_t PWM_IT_Flag)
{
	//TODO:
	return 0;
}

/**
 * @brief  : Clear PWM interrupt flag.
 * @param  : PWMx          can be PWM0/PWM1...
 * @param  : PWM_IT_Flag   can be PWM_IT_Flag_Cnt/PWM_IT_Flag_Dma/PWM_IT_Flag_Frame0...
 * @return : None.
 */
void PWM_ClearITFlag(uint8_t PWMx, uint8_t PWM_IT_Flag)
{
	//TODO:
}

/**
 * @brief  : Set PWM wave data to DMA. only use for PWM0
 * @param  : pWaveForm          Pointer point to PWM wave data buffer.
 *                            # DMA data format:
 *                               LSB   | dma length       |   pwm wave data           | MSB
 *                                     | 4B               |     N bytes               |
 *                               !!![dma length == N]
 *                            # pwm wave data format:
 *                               MSB  | pulse enable bit  | pulse select bit | the number of pulse | LSB
 *                                    |  1bit             |  1bit            |       14bit         |
 *                               !!!Note: pulse enable bit = 1  --> PWM wave will be send.
 *                                        pulse select bit = 1  --> pulse2 will be used.
 *                                        pulse select bit = 0  --> pulse  will be used.
 *
 * @param  : byteLen            the length of bytes of wave data.
 *                              !!! MAX length = 512B.
 * @return : None.
 */
void PWM_DmaSetData(uint16_t *pWaveForm, uint32_t byteLen)
{
	DMA->CHN7_ADDR = (uint16_t)(uint32_t)pWaveForm;
	DMA->CHN7_SIZE = (512>>4);//Max == 512Bytes
	DMA->CHN7_MODE &= ~DMA_MODE_WRITE_MEM;
}

/**
 * @brief  : Set PWM DMA mode enable/disable.
 * @param  : PWMx        only use for PWM0.
 * @return : None.
 */
void PWM_DmaEnable(void)
{
	DMA->CHN_EN |= DMA_CHN_PWM_EN;
	DMA->TX_TRIGGER |= DMA_TIGG_PWM_EN;
}


